#!/usr/bin/perl 
#===============================================================================
#
#         FILE:  index.cgi
#
#        USAGE:  ./index.cgi 
#
#  DESCRIPTION:  nearestCaches
#				 perl version for ufak nearestCaches service Locify
#      OPTIONS:  ---
# REQUIREMENTS:  ---
#         BUGS:  ---
#        NOTES:  ---
#       AUTHOR:  Martin Janota (mjan), <janota.m@cce.cz>
#      COMPANY:  CCE
#      VERSION:  1.0
#      CREATED:  10/09/2008 03:05:24 PM CEST
#     REVISION:  ---
#===============================================================================

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/lib";
use strict;
use TeeTemplate;
use hashes;

use Data::Dumper;
use Smart::Comments;
use Digest::MD5;
use constant DEBUG => 0;
use CGI;
use POSIX qw { strftime };
use geocaching;

our (
    %OUT,
	%IN,
);

$OUT{SERVICE_URL} = 'http://' . $ENV{SERVER_NAME};

my $Tmpl;

my %States = (
	default			=> \&default,
	settings		=> \&noscriptpage,
	first			=> \&noscriptpage,
	form			=> \&form,
	nearest			=> \&nearest,
	nearest_page	=> \&nearest_page,
	nearestMap		=> \&nearestMap,
	cache_detail	=> \&detail,
	detail			=> \&detail,
	kml				=> \&detail,
	awkml			=> \&awkml,
	logvisit		=> \&logvisit,
	showtb			=> \&showtb,
	foundtb			=> \&foundtb,
	logtb			=> \&logtb,
	routetb			=> \&routetb,
);

my $Q = CGI->new;
if ( $ENV{HTTP_COOKIE} =~ /gc_SessionId/ ) {
	set_cookies($ENV{HTTP_COOKIE});
}

if ( $ENV{QUERY_STRING}) {
	foreach ( split /(;|&)/, $ENV{QUERY_STRING}) {
		  my ($key,$val) = split '=', $_;
		  unless ( $Q->param($key)) {
		  	$Q->param($key,$val);
		  }
	}
}

#===  FUNCTION  ================================================================
#         NAME: std_page
#   PARAMETERS:  
#      RETURNS: 
#  DESCRIPTION:  spousti ftemplate na $tmpl, hodnoty jsou ulozene v %OUT
#     COMMENTS: none	
#===============================================================================

sub std_page {
	my $cookie = &get_cookies;
	if ( $cookie  ) {
		$cookie = $Q->cookie(
			-name => 'gc_SessionId',
			-value => $cookie,
			-path => '/',
			-domain => $ENV{SERVER_NAME},
		);
	} else {
		$cookie = ''
	}
	my %header = (-type => 'text/html',
			-charset => 'utf-8',
			-cookie => $cookie,
	);
	$header{'-pragma'} = 'no-cache' unless exists $OUT{nocache};
	
	if ( $Q->param('_state') && $Q->param('_state') eq 'kml') {
		$header{'-X-Cache-Store'} = "$OUT{SERVICE_URL}?_state=detail;item=listing;guid=$OUT{href}";
		$header{'-X-Cache-Store'} .= " $OUT{SERVICE_URL}?_state=detail;item=hint;guid=$OUT{href}";
		$header{'-X-Cache-Store'} .= " $OUT{SERVICE_URL}?_state=detail;item=logs;guid=$OUT{href}";
		$header{'-X-Cache-Store'} .= " $OUT{SERVICE_URL}?_state=detail;item=aw;guid=$OUT{href}" if exists $OUT{LOOP_AWS};
	}
	if ($Q->param('_state') && $Q->param('_state') eq 'awkml') {
		$header{'-X-Cache-Store'} = "$OUT{SERVICE_URL}?_state=detail;item=aw;guid=$OUT{href}";
	}

	print $Q->header(%header);
    print ftemplate(\%OUT,"$Tmpl");
}


#===  FUNCTION  ================================================================
#         NAME:  get_page
#   PARAMETERS: 
#      RETURNS:  name of function
#  DESCRIPTION:  Vraci jmeno funkce, ktera se ma provest
#     COMMENTS:  none
#===============================================================================

sub get_page {
	warn (Dumper(\{$Q->Vars}));
#	warn (Dumper(\{$Q->cookie()}));
#	warn $Q->Dump;
#	warn (Dumper(\%ENV));
	return $Q->param('_state') if $Q->param() && $Q->param('_state');
	return 'default';
}

sub noscriptpage {
	$OUT{nocache} = 1;
	$Tmpl = $Q->param('_state') . '.html';
}

#===  FUNCTION  ================================================================
#         NAME:  default
#  DESCRIPTION:  ????
#===============================================================================
sub default {
	$Tmpl = "welcome.html";
}

#===  FUNCTION  ================================================================
#         NAME:  form
#  DESCRIPTION:  ????
#===============================================================================
sub form {
	$OUT{$Q->param('_type')} = 1;
	$OUT{nocache} = 1;
	$Tmpl = "form.html";
}

#===  FUNCTION  ================================================================
#         NAME:  nearest
#  DESCRIPTION:  ????
#===============================================================================
sub nearest {
	# login to geocaching.com
	unless ( $Q->param('nologin') ) {
		if ( $Q->param('gc_user_name') && $Q->param('gc_password') ) {
			unless ( gc_login($Q->param('gc_user_name'),$Q->param('gc_password') ) ) {
				$OUT{loginError} = "Wrong username or password";
			} 
		} else {
			$OUT{loginError} = "No login data for geocaching.com";
		}
		if ( exists $OUT{loginError}  ) {
			$Tmpl = "loginError.html";
			return;
		}
	}
	# networkLink -> map view 
	if ( $Q->param('map') ) {
		$Tmpl = 'networkLink.kml';
		return;
	}

	my %param;
	foreach ( qw { shide _type oso oso_value lat lon map }) {
		$param{$_} = $Q->param($_) if $Q->param($_);
	}
	$param{shide} = 0 unless exists $param{shide};
	# search by address - with google maps api
	if ( $Q->param('_type') eq 'address' ) {
			$OUT{ADDRESSES} = get_address_latlon($Q->param('oso_value'));
			if ( scalar(@{$OUT{ADDRESSES}}) < 1) {
				$OUT{NOADDRESSES} = 1;
			}
			hash_add(\%OUT,\%param);
			$Tmpl = "googleapi.html";
			return;
	}

	# search by GC code 
	if ( $Q->param('_type') eq 'gccode' ) {
		$Q->param('_state','cache_detail');
		&detail;
		return;
	}

	($OUT{CACHES},my $pr) = gc_nearest(\%param);
	hash_add(\%OUT,$pr);
	if ( scalar(@{$OUT{CACHES}}) < 1) {
		$OUT{NOCACHE} = 1;
	}
	$Tmpl = "nearest.html";
}

# vyhledani dalsi stranky kesi
sub nearest_page {
	($OUT{CACHES},my $pr) = gc_nearest_page({ $Q->Vars });
	hash_add(\%OUT,$pr);
	if ( scalar(@{$OUT{CACHES}}) < 1) {
		$OUT{NOCACHE} = 1;
	}
	$Tmpl = "nearest.html";

}

sub nearestMap {
	$OUT{CACHES} = gc_nearest_map ( { lat => $Q->param('lat'), lon => $Q->param('lon') } );
	$OUT{MAP} = 1;
	$Tmpl = 'nearest.html';
}


#===  FUNCTION  ================================================================
#         NAME:  detail
#      RETURNS:  detail html for cache
#  DESCRIPTION:  return detail lan, lon, href, title for requested cache
#===============================================================================

sub detail {
	if ( $Q->param('item') ) {
		$OUT{item} = $Q->param('item');
		$OUT{$Q->param('item')} = 1;
	}
	my $file = "$FindBin::Bin/tmp/" . $Q->param('guid') . '.cache';
	my $cache;
	eval {
		die "$file not exists" unless ( -e $file );
		no strict;
		$cache = do $file;
		unless ( defined $cache) {
			die "Cannot read $file: $!\n";
		}
	};
	if ($@) {
		warn $@;
		$cache = gc_cache_detail($Q->param('guid'));
	}
	if ( $Q->param('item') && $Q->param('item') eq 'logvisit' ) {
		$$cache{LOOP_LOGDATE} = get_dates(); 
		hash_add(\%OUT, gc_log_params($$cache{logid}));
	}
	# zobrazuji offset + 10 logu
	if ( $Q->param('item') eq 'logs' ) {
	 	my $offset = $Q->param('offset') || 0;
		$OUT{LOOP_LOG} = [@{$$cache{LOOP_LOGS}}[($offset*10)..($offset*10 + 9 )] ];
		$OUT{offset} = ++$offset if $$cache{LOOP_LOGS}[$offset*10 + 10];
	}
	hash_add(\%OUT, $cache);
	$Tmpl = $Q->param('_state') . '.html';
}

#===  FUNCTION  ================================================================
#         NAME:  showtb
#      RETURNS:  show tb properties
#  DESCRIPTION:  
#===============================================================================

sub showtb {
	hash_add(\%OUT,gc_tb_detail($Q->param('wid')));
	$OUT{guid} = $Q->param('guid');
	$OUT{showtb} = 1;
	$Tmpl = 'tb.html'
}



#===  FUNCTION  ================================================================
#         NAME:  foundtb
#      RETURNS:  foundtb html for tb
#  DESCRIPTION:  
#===============================================================================

sub foundtb {
	hash_add(\%OUT,gc_logtb_params($Q->param('wid')));
	$OUT{LOOP_LOGDATE} = get_dates();
	$OUT{guid} = $Q->param('guid');
	$OUT{formtb} = 1;
	$Tmpl = 'tb.html'
}


#===  FUNCTION  ================================================================
#         NAME:  logtb
#      RETURNS:  logtb
#  DESCRIPTION:  
#===============================================================================

sub logtb {
	gc_tb_log($Q->param('wid'),$Q->param('logType'),$Q->param('logDate'),$Q->param('logText'), $Q->param('logTrack'), $Q->param('viewstate') );
	gc_cache_detail($Q->param('guid'));
	$OUT{title} = 'Travel Bug';
	$Tmpl = 'logsaved.html';
}


#===  FUNCTION  ================================================================
#         NAME:  routetb
#      RETURNS:  routetb
#  DESCRIPTION:  vrati tb kml file
#===============================================================================

sub routetb {
	$OUT{TBKML} = gc_tb_kml($Q->param('wid'));
	$Tmpl = 'tbkml.html';
}

#===  FUNCTION  ================================================================
#         NAME:  awkml
#      RETURNS:  kml file for additional waypoint
#  DESCRIPTION:  return detail lan, lon, href, title for requested cache
#===============================================================================

sub awkml {
	my $file = "$FindBin::Bin/tmp/" . $Q->param('guid') . '.cache';
	my $cache;
	eval {
		die "$file not exists" unless ( -e $file );
		no strict;
		$cache = do $file;
		unless ( defined $cache) {
			die "Cannot read $file: $!\n";
		}
	};
	if ($@) {
		warn $@;
		$cache = gc_cache_detail($Q->param('guid'),$Q->param('item'));
	}
	$OUT{href} = $$cache{href};
	$OUT{title} = $$cache{title};
	hash_add(\%OUT, $$cache{LOOP_AWS}[$Q->param('awid')]);
	$Tmpl = 'awkml.html';
}

sub logvisit {
	gc_cache_log($Q->param('logid'),$Q->param('logType'),$Q->param('logDate'),$Q->param('logText'), $Q->param('viewstate'), ( $Q->param('logTB') || '' ) );
	gc_cache_detail($Q->param('guid'));
#	$Q->param('item','logs');
	$Q->param('_state','logsaved');
	detail();
}
=begin  BlockComment  # BlockCommentNo_1


sub login {
#	print 'HTTP/1.0 401 UNAUTHORIZED' . "\n";
#	print "HTTP/1.0 401 Unauthorized";
	print 'WWW-Authenticate: Basic realm="Geocaching.com"' ."\n";
#	print "Content-type: text/html\n\n";
#    print ftemplate(\%OUT,"$Tmpl");
    my $cookie = $Q->cookie( -name => 'sessionId',
					-path => '/',
					-value => &create_cookie, 
	);
    print $Q->header (-type => 'text/html',
						-status => '401 Unauthorized',
						-charset => 'UTF-8',
						-connection => 'close',
	);
#						-cookie => $cookie,
	exit;
}


=end    BlockComment  # BlockCommentNo_1

=cut
sub get_dates {
	my $time = time;
	my @dates;
	$dates[0] = {
		value 	=> strftime("%m/%d/%Y", localtime($time + 60*60*24)),
		date	=> strftime("%d.%m.%Y", localtime($time + 60*60*24)),
	};
	$dates[1] = {
		value 	=> strftime("%m/%d/%Y", localtime($time)),
		date	=> strftime("%d.%m.%Y", localtime($time)),
		selected => 1,
	};

	for (my $i = 1; $i < 30; $i++ ) {
		push @dates, {
			value 	=> strftime("%m/%d/%Y", localtime($time - $i*60*60*24)),
			date	=> strftime("%d.%m.%Y", localtime($time - $i*60*60*24)),
		}
	}
	return \@dates;
}


sub create_cookie {
	return substr (Digest::MD5::md5_hex
	(Digest::MD5::md5_hex(time(). {}. rand(). $$)), 0, 32);
}

#---------------------------------------------------------------------------
#  main body
#---------------------------------------------------------------------------


my $page = &get_page || 'default';

warn($page);

&{$States{$page}};

#d(Dumper(\%OUT));

std_page($page);


